package towers;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.geom.Point2D;

import javax.swing.ImageIcon;

import core.ShootingUnit;
import enemies.Enemy;

public abstract class Tower extends ShootingUnit {

	protected Enemy aimAtEnemy;
	protected int cost;
	protected static String name;
	protected int level = 1;
	protected int maxLevel = 10;

	/**
	 * 
	 * @param position Positie van de toren
	 * @param health Health van de toren
	 * @param image Het plaatje wat voor de toren gebruikt word
	 * @param size De grootte van een toren
	 * @param viewAngle De begin-kijkhoek van een toren
	 * @param range De afstand wat een toren kan schieten
	 * @param firerate Hoe snel een toren kan schieten
	 * @param cost Hoe duur een toren is
	 */
	public Tower(Point2D.Double position, int health, ImageIcon image, Dimension size, int viewAngle, int range, int firerate, int cost) {
		super(position, health, image, size, viewAngle, range, firerate);
		
		this.cost = cost;
	}

	/**
	 * Returnt de vijand waar de toren op dit moment mee bezig is
	 * @return the aimAtEnemy
	 */
	public Enemy getAimAtEnemy() {
		return aimAtEnemy;
	}

	/**
	 * Verandert de enemy waar de toren op dit moment op richt
	 * @param aimAtEnemy
	 *            the aimAtEnemy to set
	 */
	public void setAimAtEnemy(Enemy aimAtEnemy) {
		this.aimAtEnemy = aimAtEnemy;
	}

	/**
	 * @return Kosten van de toren
	 */
	public int getCost() {
		return cost;
	}
	
	public double getDamageMultiplier()
	{
		return getLevel() * 2.5;
	}
	
	public abstract int getDamage();
	
	/**
	 * Berekent het midden van een enemy
	 * @return Middelpunt van een enemy
	 */
	
	public Point2D.Double getForesideEnemy(){
		return aimAtEnemy.getMiddle();
	}
	
	/**
	 * Viewangle aanpassen, moet wijzen naar enemy
	 * @return boolean Geeft true terug als er iets veranderd
	 */
	protected boolean aimAtEnemy() {
		if ( this.position != null && aimAtEnemy != null ) {
			Point2D.Double enemyPos = aimAtEnemy.getPosition();
			double x = enemyPos.getX()-position.x;
			double y = enemyPos.getY()-position.y;
			
			//vijand links van toren
			if( x < 0 ){
				//vijand hoger dan toren
				x *= -1;
				if( y < 0 ){
					y *= -1;
					viewAngle = (int)Math.toDegrees( (Math.atan( ( y/x )   )) ) + 90 ;
				}
				//vijand lager dan toren
				else if( y > 0 ){
					viewAngle = (int)Math.toDegrees( (Math.atan( ( x/y )   )) );
				}
			//vijand rechts van toren
			} else if( x >= 0 ){
				if( y < 0 ){
					y *= -1;
					viewAngle = (int)Math.toDegrees( (Math.atan( ( x/y )   )  ) )+ 180;
				} else if( y > 0 ){
					viewAngle = (int)Math.toDegrees( (Math.atan( ( y/x  )   ))   )+ 270;
				}
			}
			
			return true;
		}
		
		return false;
	}
	
	public boolean update() {
		// Is de enemy al dood?
		if ( aimAtEnemy != null && aimAtEnemy.getHealth() <= 0 ){
			aimAtEnemy = null;
		}
		
		return super.update();
	}
	
	public void updateLevel(){
		if(this.getLevel() <this.getMaxLevel()){
			//alleen als het level nog geen 10 is dan mag die omhoog
			this.level++;
			this.health = this.getMaxHealth();
		}
	}
	
	public int getMoneyRequiredForUpgrade()
	{
		return (int)( getCost() * getLevel() * 0.50);
	}
	
	public int getMoneyRequiredForRepair()
	{
		return (int)( getCost() * (1-getHealthPercentage()) * 0.50);
	}
	
	/**
	 * @return berekend firerate
	 */
	public int getFirerate() {
		return (int)( firerate * ( Math.pow(1.15, level)));
	}
	
	/**
	 * @return berekend bereik
	 */
	public int getRange() {
		return (int)(range * ( Math.pow(1.1, level)));
	}
	
	public int getLevel(){
		return this.level;
	}
	
	public int getMaxLevel(){
		return this.maxLevel;
	}
	
	/**
	 * @return the maxHealth
	 */
	public int getMaxHealth() {
		if(this.level>1){
			return (int) (this.maxHealth * (this.level*0.8));
		}else{
			return this.maxHealth;
		}
	}
	
	/*
	 * @see core.Unit#draw(java.awt.Graphics, java.awt.Rectangle,
java.awt.Component)
	 */
	public void draw(Graphics g, Rectangle area, Component c )
	{
		super.draw(g, area, c);
		
		// Shaduw level
		g.setColor( Color.BLACK );
		g.setFont( new Font("Arial", Font.PLAIN, 9) );
		g.drawString( "lvl "+this.getLevel(), (int)position.x + size.width - 13, (int)position.y + size.height + 2);
		
		// level
		g.setColor( Color.WHITE );
		g.setFont( new Font("Arial", Font.PLAIN, 9) );
		g.drawString( "lvl "+this.getLevel(), (int)position.x + size.width - 15, (int)position.y + size.height);
	}
	
	public int getSellProfit() {
		// De opbrengsten zijn 75% van de originele kosten, maal health percentage
		return (int) (0.75 * getCost() * Math.max(getLevel() - 1, 1) * getHealthPercentage());
	}

}
